#pragma once
#include "..\interfaces.h"
#include "ZipResourceLoader.h"
#include "NoResourceFile.h"
#include <map>
#include <list>
#include "..\RandomEngine.h"
class ResCache;
class ResHandle : public IResHandle
{
	friend ResCache;
public:
	ResHandle(IResCache & Cache, const RE::IO::FilePath & res) : m_origin(res) {  m_Cache = &Cache; m_buffer = NULL; };
	~ResHandle();
	unsigned int VGetSize() { return m_size; }
	char* VGetBuffer() { return m_buffer; }
	const RE::IO::FilePath& VGetResource() { return m_origin; }
protected:
	unsigned int m_size;
	char * m_buffer;
	IResCache * m_Cache;
	const RE::IO::FilePath m_origin;
};
class ResCache : public IResCache
{
public:
	friend ResHandle;
	ResCache(unsigned int Bytes_Cap);
	~ResCache();

	//ResourceHandle & Holder Managment
	ResHandlePtr	VGetHandle(const Resource &res);

	//ResourceFile Managment
	unsigned int VAddResourceFile(RE::IO::FilePath & path, ResourceFilePtr ResFile); // if return 0 -> something went wrong
	bool VRemoveResourceFile(RE::IO::FilePath & path, bool RemoveHandles);
	unsigned int VGetResFileIdByFileName(const std::string & str);

	//Cache Managment
	void VSetBytesCap(unsigned int bytes) { m_ByteCap = bytes; };
	unsigned int VGetBytesCap() { return m_ByteCap; };
	unsigned int VGetUsedBytes() { return m_BytesUsed; };
	void VFreeMemory(unsigned int bytes);

	void VBytesReleased(const unsigned int bytes) { m_BytesUsed -= bytes; };
	void VBytesAllocated(const unsigned int bytes) { m_BytesUsed += bytes; };
private:
	//Resource Handle Managment
	ResHandlePtr FindHandle( const Resource &res);
	void UpdateHandle(ResHandlePtr handle);
	ResHandlePtr LoadHandle( const Resource &res);
	void RemoveHandle(ResHandlePtr handle);
	bool FreeLeastRecentUsedHandle();
	//ResourceFIle Managment
	unsigned int GetNewResFileId() { return ++m_LastResourceFileId; }
	unsigned int m_LastResourceFileId;	
	unsigned int GetResFileIdByFileName(Resource & res);
	//Cache Managment
	unsigned int m_ByteCap;
	unsigned int m_BytesUsed;

	ResourceFileMap m_ResourceFileMap; // id + isntance of the resource file classs
	ResHandleList m_LeastRecentUsed;
	ResHandleMap m_Resources; // List < file id, pair< string - filename, Handle > >
};
